import {
  BlockhashWithExpiryBlockHeight,
  Connection,
  Keypair,
  Transaction,
  VersionedTransaction,
} from '@solana/web3.js';
import { TransactionExecutor } from './transaction-executor.interface';
import { logger } from '../helpers';
import { retry } from '../utils/utils';

export class DefaultTransactionExecutor implements TransactionExecutor {
  constructor(private readonly connection: Connection) {}

  // public async executeAndConfirm(
  //   transaction: VersionedTransaction,
  //   payer: Keypair,
  //   latestBlockhash: BlockhashWithExpiryBlockHeight,
  // ): Promise<{ confirmed: boolean; signature?: string; error?: string }> {
  //   // logger.debug('Executing transaction...');
  //   logger.debug(' 开始执行交易...');
  //   let signature = '';
  //   signature = await retry(
  //     async () => (signature = await this.execute(transaction)),
  //     { retryIntervalMs: 10, retries: 50 }, // 重试设置
  //   );

  //   logger.debug({ signature }, 'Confirming transaction...');
  //   return this.confirm(signature, latestBlockhash);
  // }

  public async executeAndConfirm(
    transaction: VersionedTransaction,
    payer: Keypair,
    latestBlockhash: BlockhashWithExpiryBlockHeight,
  ): Promise<{ confirmed: boolean; signature?: string; error?: string }> {
    logger.debug(' 开始执行交易...');

    const signature = await retry(() => this.execute(transaction), { retryIntervalMs: 10, retries: 50 });

    logger.debug({ signature }, '确认交易...');
    return this.confirm(signature, latestBlockhash);
  }

  private async execute(transaction: Transaction | VersionedTransaction) {
    return this.connection.sendRawTransaction(transaction.serialize(), {
      preflightCommitment: this.connection.commitment,
      skipPreflight: true, // 跳过预执行
    });
  }

  private async confirm(signature: string, latestBlockhash: BlockhashWithExpiryBlockHeight) {
    const confirmation = await this.connection.confirmTransaction(
      {
        signature,
        lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
        blockhash: latestBlockhash.blockhash,
      },
      this.connection.commitment,
    );

    return { confirmed: !confirmation.value.err, signature };
  }
}
